package redora.performance.runners;

import redora.api.fetch.Page;
import redora.api.fetch.Scope;
import redora.exceptions.RedoraException;
import redora.performance.PerformanceTest;
import redora.performance.rdo.model.PerformanceParent;
import redora.performance.rdo.service.PerformanceParentService;
import redora.performance.rdo.service.ServiceFactory;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

/** This test checks the performance of the persistence layer. */
public class RedoraRunner {

    public static void main(String[] args) throws RedoraException, IOException {
        run(25);
    }

    public static long[] run(int size) throws RedoraException, IOException {
        PerformanceTest.prepare();
        long[] ret = { 99999999999999L, 99999999999999999L, 9999999999999999L, 9999999999999999L,
                9999999999999999L, 9999999999999999L };

        ret[0] = insert(size);
        ret[1] = retrieve();
        ret[2] = perObject(size);
        ret[3] = update();
        long[] json = json();
        ret[4] = json[0];
        ret[5] = json[1];

        return ret;
    }

    private static long insert(int count) throws RedoraException {
        long start = System.nanoTime();
        List<PerformanceParent> insert = new LinkedList<PerformanceParent>();
        for (int i = 0; i < count; i++) {
            PerformanceParent p = new PerformanceParent();
            p.setSmalltext("text" + i);
            p.setNumber(new Random(i).nextInt());
            insert.add(p);
        }
        ServiceFactory.performanceParentService().persist(insert);
        return Math.abs(System.nanoTime() - start);
    }

    private static long retrieve() throws RedoraException {
        long start = System.nanoTime();
        List<PerformanceParent> all = ServiceFactory.performanceParentService().findAll(
                Page.ALL_TABLE);
        for (PerformanceParent p : all)
            if (!p.getSmalltext().equals("nomatch"))
                p.getNumber();
        return Math.abs(System.nanoTime() - start);
    }

    private static long perObject(int count) throws RedoraException {
        insert(count);
        long start = System.nanoTime();
        PerformanceParentService service = ServiceFactory.performanceParentService();
        for (long i = 1; i < count; i++) {
            PerformanceParent p = service.findById(i, Scope.Form);
            p.getCreationDate();
        }
        return Math.abs(System.nanoTime() - start);
    }

    private static long update() throws RedoraException {
        List<PerformanceParent> all = ServiceFactory.performanceParentService().findAll(
                Page.ALL_TABLE);
        long start = System.nanoTime();
        for (PerformanceParent p : all)
            if (!p.getSmalltext().equals("nomatch")) {
                p.setNumber(new Random().nextInt());
                p.setSmalltext("text");
            }
        ServiceFactory.performanceParentService().persist(all);

        return Math.abs(System.nanoTime() - start);
    }

    private static long[] json() throws RedoraException, IOException {
        long[] retval = { 999999999999L, 99999999999999L };

        File tmp = File.createTempFile("jsonRedora", ".tmp");
        PrintWriter out = new PrintWriter(tmp);

        long start = System.nanoTime();
        ServiceFactory.performanceParentServiceJSON().findAll(Page.ALL_TABLE, out);
        out.close();
        retval[0] = Math.abs(System.nanoTime() - start);
        retval[1] = tmp.length();
        tmp.delete();

        return retval;
    }
}
